home *** CD-ROM | disk | FTP | other *** search
/ Aminet 22 / Aminet 22 (1997)(GTI - Schatztruhe)[!][Dec 1997].iso / Aminet / dev / src / RLD_source.lha / RLD_source / rexx_supp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-22  |  6.4 KB  |  241 lines

  1. /*
  2.   $Id: rexx_supp.c,v 1.2 1997/10/21 22:35:08 wegge Stab wegge $
  3.   
  4.   $Log: rexx_supp.c,v $
  5.   Revision 1.2  1997/10/21 22:35:08  wegge
  6.   Snapshot inden upload af 2.13 i source og binær form
  7.  
  8.   Revision 1.1  1997/10/21 03:49:58  wegge
  9.   Initial revision
  10.  
  11.  */
  12.  
  13.  
  14. #include "rexx_gls.h"
  15.  
  16. /* Out of sheer lazyness, we create a global visible copy of our
  17.    library base pointer. We declare it here, instead of in libinit.c,
  18.    which will be kept totally unaware of it's existance, simply to
  19.    avoid confusion. We also keep a copy of the librarybase for
  20.    Utility.library, to ease the job for the assembler stub. */
  21.  
  22. struct RexxGLSBase *RglsBase = NULL;
  23. struct UtilityBase *_UtilBase = NULL;
  24.  
  25.  
  26. #include "rexx_supp_priv.h"
  27. #include "localerexx_protos.h"
  28. #include "localerexx.h"
  29. #include "rexx_supp_protos.h"
  30. #include "functabl.h"
  31. #include "rxslibinlines.h"
  32.  
  33. /* ARexx calls us here each time it need to query for a function. We
  34.    get a standard RexxMsg packet, which cointains the name and
  35.    arguments for the needed function. Unfortunately ARexx expects
  36.    two returns, an error code in d0, and a pointer to an argstring
  37.    with the result in a1. 
  38.    
  39.    As a consequence, we are going through this handcrafted piece of
  40.    obfuscated m68k code.
  41.    */
  42.  
  43. VOID ArexxMatchPoint(struct RexxMsg * __asm("a1"),
  44.                      struct RexxGLSBase * __asm("a6"));
  45. __asm("
  46. .even
  47. .globl _ArexxMatchPoint
  48. _ArexxMatchPoint:
  49.  
  50. link a5,#-8    | Storage for the return values
  51. lea a5@(-8),a1    | Address of struct RetVal
  52. movel a6,sp@-    | struct RexxGLSBase *LibBase
  53. movel a0,sp@-    | struct RexxMsg *Message
  54. movel a1,sp@-    | Address for the return struct
  55. jsr _QueryPoint    | Call QueryPoint(&RetVal, Message, LibBase)
  56. addw #12,sp    | Clean up
  57. movel a5@(-4),a0| a0 = RexxMatch_ret.ArgStr (Blast lousy docs!!)
  58. movel a5@(-8),d0| d0 = RexxMatch_ret.Error
  59. unlk a5         | Release storage
  60. rts
  61. ");
  62.  
  63. /* The Arexx Match Func. */
  64.  
  65.  
  66. VOID QueryPoint(struct RexxMatch_ret * RV, struct RexxMsg * RMsg,
  67.         struct RexxGLSBase * RglsBase_arg) 
  68. {
  69.  
  70.   /* This is where the actual work will be done. The RexxMsg contains
  71.      the name of the needed function in ARG0, with its arguments in
  72.      ARG1..ARGxx. We do a bisection of the functable, which much be
  73.      sorted in ascending order (case insensitive), so that we don't
  74.      use inordinate amounts of time here. */
  75.  
  76.   VOID(*Func) (struct RexxMatch_ret *, struct RexxMsg *);
  77.   LONG Min = 0, Mid = 0, Max = JTABL_ENTRIES - 1;
  78.   LONG TestRes;
  79.  
  80.   /* Since we are now in a somewhat safer environment now, we'll
  81.      perform the initialization that we couldn't do in libinit. If our
  82.      global copy of RglsBase is NULL, we can be reasonably sure that
  83.      this is the first invocation, but to protect against race
  84.      conditions, we will then aquire the semaphore, and check again. */
  85.   
  86.   RglsBase = RglsBase_arg;
  87.   KPRINTF_HERE;
  88.  
  89.   if (_UtilBase == NULL)
  90.     {
  91.       ObtainSemaphore(&RglsBase_arg->RexxGLS_Sem);
  92.       if (_UtilBase == NULL)
  93.     {
  94.       if (PerformInit() == DOSFALSE)
  95.         {
  96.  
  97.           /* What gives? We're somewhat stuck, since we might be
  98.          missing rexxsyslib.library (For some obscure
  99.          reason). */
  100.           ReleaseSemaphore(&RglsBase_arg->RexxGLS_Sem);
  101.           RV->ArgStr = NULL;
  102.           RV->Error = ERR10_014; /* Required library not found. */
  103.           return;
  104.         }
  105.     }
  106.       ReleaseSemaphore(&RglsBase_arg->RexxGLS_Sem);
  107.     }
  108.   
  109.   while ((Max >= 0) && (Min < JTABL_ENTRIES) && (Min <= Max))
  110.     {
  111.       Mid = (Min + Max) / 2;
  112.       
  113.       /* ARexx mangles names into uppercase (mostly), so we has to do
  114.      a case insensitive comparision. */
  115.  
  116.       TestRes = StrcmpU(RMsg->rm_Args[0], jt[Mid].FuncName, jt[Mid].StrLen);
  117.  
  118.       
  119.       if (TestRes < 0)
  120.     Min = (Mid + 1);
  121.  
  122.       if (TestRes == 0)
  123.     {
  124.  
  125.       /* The name match, now let's see if the argument count is
  126.          within the useful range. */
  127.       if ((jt[Mid].MinArg <= (RMsg->rm_Action & RXARGMASK)) &&
  128.           (jt[Mid].MaxArg >= (RMsg->rm_Action & RXARGMASK)))
  129.         {
  130.           /* They were. */
  131.           Func = jt[Mid].Func;
  132.           (*Func) (RV, RMsg);
  133.           return;
  134.         }
  135.       /* Nope, we return an error. */
  136.       RV->ArgStr = CreateArgstring("", 0);
  137.       RV->Error = ERR10_017; /* Wrong number of arguments */
  138.       SetRexxRC(RMsg, RC_ERROR);
  139.       return;
  140.     }
  141.  
  142.       if (TestRes > 0)
  143.     Max = (Mid - 1);
  144.     }
  145.   
  146.   /* The requested function is not one of ours. To indicate this, we
  147.      return an empty ArgString and ERR10_001. */
  148.  
  149.   RV->ArgStr = CreateArgstring("", 0);
  150.   RV->Error = ERR10_001;    /* Program not found. */
  151. }
  152.  
  153. VOID SetRexxRC(struct RexxMsg *RMsg, LONG RC_Val)
  154. {
  155.  
  156.   /* Set the variable RC in the current ARexx environment to the value
  157.      RC_Val. */
  158.  
  159.   UBYTE *ArgString;
  160.   struct RexxArg *RxArg;
  161.   KPRINTF_HERE;
  162.  
  163.   ArgString = CVi2arg(RC_Val, 0);
  164.   RxArg = (struct RexxArg *) (ArgString - 8);
  165.  
  166.   SetRexxVar((struct Message *) RMsg, "RC", ArgString, RxArg->ra_Length);
  167.   DeleteArgstring(ArgString);
  168.  
  169. }
  170.  
  171. BOOL
  172. PerformInit(VOID)
  173. {
  174.   BOOL RV = DOSTRUE;
  175.   KPRINTF_HERE;
  176.  
  177.   RglsBase->rgls_DOSBase = (struct DosLibrary *)
  178.     OpenLibrary( "dos.library", 37L);
  179.   if (!RglsBase->rgls_DOSBase)
  180.     RV = DOSFALSE;
  181.   
  182.   RglsBase->rgls_RexxSysBase = (struct RxsLib *)
  183.     OpenLibrary( "rexxsyslib.library", 36L);
  184.   if (!RglsBase->rgls_RexxSysBase)
  185.     RV = DOSFALSE;
  186.   
  187.   RglsBase->rgls_UtilityBase = (struct UtilityBase *)
  188.     OpenLibrary( "utility.library", 37L);
  189.   if (!RglsBase->rgls_UtilityBase)
  190.     RV = DOSFALSE;
  191.   
  192.   RglsBase->rgls_LocaleBase = (struct LocaleBase *)
  193.     OpenLibrary( "locale.library", 37L);
  194.   if (!RglsBase->rgls_LocaleBase)
  195.     RV = DOSFALSE;
  196.  
  197.   if (RV == DOSFALSE)
  198.     {
  199.       if (RglsBase->rgls_DOSBase != NULL)
  200.     CloseLibrary ((struct Library *)RglsBase->rgls_DOSBase);
  201.       
  202.       if (RglsBase->rgls_RexxSysBase != NULL)
  203.     CloseLibrary ((struct Library *)RglsBase->rgls_RexxSysBase);
  204.       
  205.       if (RglsBase->rgls_UtilityBase != NULL)
  206.     CloseLibrary ((struct Library *)RglsBase->rgls_UtilityBase);
  207.       
  208.       if (RglsBase->rgls_LocaleBase != NULL)
  209.     CloseLibrary ((struct Library *)RglsBase->rgls_LocaleBase);
  210.     }
  211.   
  212.   _UtilBase = RglsBase->rgls_UtilityBase;
  213.  
  214.   return (RV);
  215. }
  216.  
  217.  
  218. /* Since we dont link with the standard library, we'll have to provide
  219.    the required math functions. The easy way around this problem, is
  220.    utility.library/UDivMod32, which can handle our exact needs. */
  221.  
  222. __asm("
  223. .globl  ___umodsi3
  224. .globl  ___udivsi3
  225. .even
  226.  
  227. | d1 = d0 % d1 (unsigned)
  228.  
  229. ___umodsi3:    moveml sp@(4:w),d0/d1
  230. jbsr udivsi3x
  231. movel d1,d0
  232. rts
  233.  
  234. | d1 = d0 / d1 (unsigned)
  235.         
  236. ___udivsi3:    moveml sp@(4:w),d0/d1
  237. udivsi3x:
  238. movel __UtilBase,a0
  239. jmp a0@(-0x9c:w)
  240. ");
  241.